package com.kwdb.importtool.config;

import com.typesafe.config.Config;
import com.typesafe.config.ConfigFactory;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;

/**
 * 迁移配置类
 * 配置迁移过程中的各种参数和行为
 */
@Data
public class MigrationConfig {
    private static final Logger logger = LoggerFactory.getLogger(MigrationConfig.class);

    // 文件处理配置
    private String sqlFilePath;
    private String outputDir;
    private String tempDir;
    private boolean backupOriginal;
    private String backupDir;

    // 迁移行为配置
    private boolean createDatabase = true;
    private boolean createTables = true;
    private boolean importData = true;
    private boolean createIndexes = true;
    private boolean createSequences = true;
    private boolean includeComments = true;

    // 性能配置
    private int batchSize = 1000;
    private int commitSize = 5000;
    private int maxThreads = 4;
    private boolean parallelMigration = false;
    private int queryTimeout = 300;

    // 错误处理配置
    private boolean skipErrors = false;
    private int maxErrorCount = 100;
    private boolean stopOnCriticalError = true;
    private boolean logErrorsOnly = false;

    // 验证配置
    private boolean validateSchema = true;
    private boolean validateDataCount = true;
    private boolean validateDataContent = false;
    private int samplingSize = 1000;

    // 日志配置
    private boolean verboseLogging = false;
    private boolean logToFile = true;
    private String logFile;
    private boolean showProgress = true;

    // SQL转换配置
    private boolean convertDataTypes = true;
    private boolean convertIndexes = true;
    private boolean convertConstraints = true;
    private boolean removeUnsupportedSyntax = true;
    private boolean addIfNotExists = true;

    private static final String DEFAULT_CONFIG_FILE = "application.conf";

    public MigrationConfig() {
        loadDefaultConfig();
    }

    public MigrationConfig(String configFilePath) {
        loadConfigFromFile(configFilePath);
    }

    /**
     * 从默认配置文件加载配置
     */
    private void loadDefaultConfig() {
        try {
            Config config = ConfigFactory.load(DEFAULT_CONFIG_FILE);
            loadConfig(config);
            logger.info("Loaded migration configuration from default config file");
        } catch (Exception e) {
            logger.warn("Failed to load default config file, using default values", e);
            setDefaultValues();
        }
    }

    /**
     * 从指定文件加载配置
     */
    private void loadConfigFromFile(String configFilePath) {
        try {
            File configFile = new File(configFilePath);
            if (configFile.exists()) {
                Config config = ConfigFactory.parseFile(configFile);
                loadConfig(config);
                logger.info("Loaded migration configuration from: {}", configFilePath);
            } else {
                logger.warn("Config file not found: {}, using default config", configFilePath);
                loadDefaultConfig();
            }
        } catch (Exception e) {
            logger.error("Error loading config file: {}", configFilePath, e);
            loadDefaultConfig();
        }
    }

    /**
     * 从Config对象加载配置
     */
    private void loadConfig(Config config) {
        try {
            // 文件处理配置
            this.sqlFilePath = config.getString("migration.file.sql-file-path");
            this.outputDir = config.getString("migration.file.output-dir");
            this.tempDir = config.getString("migration.file.temp-dir");
            this.backupOriginal = config.getBoolean("migration.file.backup-original");
            this.backupDir = config.getString("migration.file.backup-dir");

            // 迁移行为配置
            this.createDatabase = config.getBoolean("migration.behavior.create-database");
            this.createTables = config.getBoolean("migration.behavior.create-tables");
            this.importData = config.getBoolean("migration.behavior.import-data");
            this.createIndexes = config.getBoolean("migration.behavior.create-indexes");
            this.createSequences = config.getBoolean("migration.behavior.create-sequences");
            this.includeComments = config.getBoolean("migration.behavior.include-comments");

            // 性能配置
            this.batchSize = config.getInt("migration.performance.batch-size");
            this.commitSize = config.getInt("migration.performance.commit-size");
            this.maxThreads = config.getInt("migration.performance.max-threads");
            this.parallelMigration = config.getBoolean("migration.performance.parallel");
            this.queryTimeout = config.getInt("migration.performance.query-timeout");

            // 错误处理配置
            this.skipErrors = config.getBoolean("migration.error-handling.skip-errors");
            this.maxErrorCount = config.getInt("migration.error-handling.max-error-count");
            this.stopOnCriticalError = config.getBoolean("migration.error-handling.stop-on-critical-error");
            this.logErrorsOnly = config.getBoolean("migration.error-handling.log-errors-only");

            // 验证配置
            this.validateSchema = config.getBoolean("migration.validation.validate-schema");
            this.validateDataCount = config.getBoolean("migration.validation.validate-data-count");
            this.validateDataContent = config.getBoolean("migration.validation.validate-data-content");
            this.samplingSize = config.getInt("migration.validation.sampling-size");

            // 日志配置
            this.verboseLogging = config.getBoolean("migration.logging.verbose-logging");
            this.logToFile = config.getBoolean("migration.logging.log-to-file");
            this.logFile = config.getString("migration.logging.log-file");
            this.showProgress = config.getBoolean("migration.logging.show-progress");

            // SQL转换配置
            this.convertDataTypes = config.getBoolean("migration.conversion.convert-data-types");
            this.convertIndexes = config.getBoolean("migration.conversion.convert-indexes");
            this.convertConstraints = config.getBoolean("migration.conversion.convert-constraints");
            this.removeUnsupportedSyntax = config.getBoolean("migration.conversion.remove-unsupported-syntax");
            this.addIfNotExists = config.getBoolean("migration.conversion.add-if-not-exists");

        } catch (Exception e) {
            logger.warn("Error loading specific migration config, using defaults for missing values", e);
            // 使用默认值继续
        }
    }

    /**
     * 设置默认值
     */
    private void setDefaultValues() {
        // 文件处理默认配置
        this.outputDir = System.getProperty("user.dir") + "/output";
        this.tempDir = System.getProperty("java.io.tmpdir") + "/kwdb-migration";
        this.backupOriginal = true;
        this.backupDir = System.getProperty("user.dir") + "/backup";

        // 日志默认配置
        this.logFile = System.getProperty("user.dir") + "/logs/migration.log";
    }

    /**
     * 验证配置是否有效
     */
    public boolean isValid() {
        if (sqlFilePath == null || sqlFilePath.trim().isEmpty()) {
            logger.error("SQL file path is required");
            return false;
        }

        // 检查文件是否存在
        File sqlFile = new File(sqlFilePath);
        if (!sqlFile.exists() || !sqlFile.isFile()) {
            logger.error("SQL file does not exist or is not a file: {}", sqlFilePath);
            return false;
        }

        // 检查文件扩展名
        if (!sqlFilePath.toLowerCase().endsWith(".sql")) {
            logger.warn("SQL file extension is not .sql: {}", sqlFilePath);
        }

        return true;
    }

    /**
     * 获取有效的输出目录
     */
    public String getEffectiveOutputDir() {
        if (outputDir != null && !outputDir.trim().isEmpty()) {
            return outputDir;
        }
        return System.getProperty("user.dir") + "/output";
    }

    /**
     * 获取有效的临时目录
     */
    public String getEffectiveTempDir() {
        if (tempDir != null && !tempDir.trim().isEmpty()) {
            return tempDir;
        }
        return System.getProperty("java.io.tmpdir") + "/kwdb-migration";
    }

    /**
     * 获取有效的日志文件路径
     */
    public String getEffectiveLogFile() {
        if (logFile != null && !logFile.trim().isEmpty()) {
            return logFile;
        }
        return System.getProperty("user.dir") + "/logs/migration.log";
    }

    /**
     * 是否应该执行完整迁移
     */
    public boolean shouldExecuteFullMigration() {
        return createDatabase || createTables || importData || createIndexes || createSequences;
    }

    /**
     * 是否应该验证迁移结果
     */
    public boolean shouldValidateMigration() {
        return validateSchema || validateDataCount || validateDataContent;
    }

    @Override
    public String toString() {
        return "MigrationConfig{" +
                "sqlFilePath='" + sqlFilePath + '\'' +
                ", outputDir='" + outputDir + '\'' +
                ", createDatabase=" + createDatabase +
                ", createTables=" + createTables +
                ", importData=" + importData +
                ", batchSize=" + batchSize +
                ", skipErrors=" + skipErrors +
                ", validateSchema=" + validateSchema +
                '}';
    }
}